// handlers/projects.go
// Contains project-level handler functions and supporting DTOs.

package handlers

import (
	"net/http"

	"github.com/gin-gonic/gin"

	"agentdesign/models"
)

// ListProjects responds with the available projects.
func (h *Handler) ListProjects(c *gin.Context) {
	projects, err := h.service.ListProjects()

	result := Result[[]models.Project]{
		Code: http.StatusOK,
		Data: projects,
		Msg:  ResponseMessage.SUCCESS,
	}

	if err != nil {
		result.Code = http.StatusInternalServerError
		result.Msg = err.Error()
	}

	c.JSON(result.Code, result)
}

// CreateProjectRequest mirrors the expected fields for POST /api/projects.
// The binding:"required" tag tells Gin's ShouldBindJSON to validate that these fields
// are present and non-empty in the incoming JSON request. If validation fails,
// ShouldBindJSON returns an error that can be handled in the handler function.
type CreateProjectRequest struct {
	Name        string `json:"name" binding:"required"`     // Must be present and non-empty
	Description string `json:"description"`                 // Optional field, no validation
	Platform    string `json:"platform" binding:"required"` // Must be present and non-empty
}

// CreateProject returns a placeholder response until persistence is implemented.
func (h *Handler) CreateProject(c *gin.Context) {
	var req CreateProjectRequest
	result := Result[int64]{
		Code: http.StatusOK,
		Data: 0,
		Msg:  ResponseMessage.SUCCESS,
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		result.Code = http.StatusBadRequest
		result.Msg = err.Error()
		c.JSON(result.Code, result)

		return
	}

	id, err := h.service.CreateProject(models.Project{
		Name:        req.Name,
		Description: req.Description,
		Platform:    req.Platform,
	})
	if err != nil {
		result.Code = http.StatusInternalServerError
		result.Msg = err.Error()
		c.JSON(result.Code, result)

		return
	}

	result.Data = id

	c.JSON(result.Code, result)
}

// GetProject returns detail for a single project by identifier.
func (h *Handler) GetProject(c *gin.Context) {
	id := c.Params.ByName("id")
	project, err := h.service.GetProject(id)

	result := Result[models.Project]{
		Code: http.StatusOK,
		Data: project,
		Msg:  ResponseMessage.SUCCESS,
	}

	if err != nil {
		result.Code = http.StatusInternalServerError
		result.Msg = err.Error()
	}

	c.JSON(result.Code, result)
}

// UpdateProjectRequest mirrors the fields accepted for full updates.
type UpdateProjectRequest struct {
	ID          string `json:"id" binding:"required"`
	Name        string `json:"name" binding:"required"`
	Description string `json:"description"`
	Platform    string `json:"platform" binding:"required"`
}

// UpdateProject is a placeholder implementation.
func (h *Handler) UpdateProject(c *gin.Context) {
	var req UpdateProjectRequest
	result := Result[bool]{
		Code: http.StatusOK,
		Data: false,
		Msg:  ResponseMessage.SUCCESS,
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		result.Code = http.StatusBadRequest
		result.Msg = err.Error()
		c.JSON(result.Code, result)

		return
	}

	rows, err := h.service.UpdateProject(models.Project{
		ID:          req.ID,
		Name:        req.Name,
		Description: req.Description,
		Platform:    req.Platform,
	})

	if err != nil {
		result.Code = http.StatusInternalServerError
		result.Msg = err.Error()
		c.JSON(result.Code, result)

		return
	}

	result.Data = rows > 0

	c.JSON(result.Code, result)
}

// DeleteProject returns a placeholder message.  The actual deletion logic will
// be implemented once the persistence layer is in place.
func (h *Handler) DeleteProject(c *gin.Context) {
	id := c.Params.ByName("id")
	result := Result[bool]{
		Code: http.StatusOK,
		Data: false,
		Msg:  ResponseMessage.SUCCESS,
	}

	rows, err := h.service.DeleteProject(id)
	if err != nil {
		result.Code = http.StatusInternalServerError
		result.Msg = err.Error()
		c.JSON(result.Code, result)

		return
	}

	result.Data = rows > 0

	c.JSON(result.Code, result)
}
